{
  // 因为泛型是个类型变量, 所有具体类型是不明确的, 使用数据时 就不会有对应的提示
  // 泛型约束
  // 1. 直接指定特定的类型
  function id<T>(value: T[]): T[] {
    // 在定义泛型T时, 不知道具体的类型
    console.log(value.length)
    return value
  }

  id<string>(['a', 'b'])

  // 2. 添加约束,
  interface Ilength {
    length: number
  }

  function id1<T extends Ilength>(value: T): T {
    console.log(value.length)
    return value
  }

  //   id1(1)
  id1<string>('abcdefg')
  id1<number[]>([1, 2, 3, 4])
}

{
  // 练习: 定义一个泛型函数, getProperty
  const obj = { name: 'cxk', age: 25, desc: '时长两年半' }
  // getProperty(obj, 'name') => 'zs'

  // Key 有要求, 不能是随意的字符串 必须是存在的属性名 'name' | 'age'
  function getProperty<Type, Key extends keyof Type>(obj: Type, key: Key) {
    return obj[key]
  }

  // 泛型key被要求是 泛型Type的键组成的联合类型 => keyof
  //keyof 关键字接收一个对象类型，生成其键名称(可能是字符串或数字)的联合类型。
  const res = getProperty(obj, 'name')
  console.log(res, '是谁')

  const res1 = getProperty(obj, 'age')
  console.log(res1, '年龄')

  // type ObjType = {
  //   name: string
  //   age: number
  //   single: boolean
  // }
}
